package com.stars.easyms.demo.restservice.sentinel;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.stars.easyms.demo.dto.input.sentinel.SentinelDemo3Input;
import com.stars.easyms.demo.dto.output.sentinel.SentinelDemo3Output;
import com.stars.easyms.rest.RestService;
import com.stars.easyms.base.util.MessageFormatUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class SentinelDemo3Service implements RestService<SentinelDemo3Input, SentinelDemo3Output> {

    private static final String RESOURCE_NAME = SentinelDemo3Service.class.getSimpleName();

    @Override
    public SentinelDemo3Output execute(SentinelDemo3Input input) {
        defineDegradeRule(input);
        int successCount = 0, blockCount = 0;
        for (int i = 0; i < input.getTimes(); i++) {
            // 循环times次，如果阈值达到则限流抛出BlockException
            try {
                try (Entry entry = SphU.entry(RESOURCE_NAME)) {
                    successCount++;
                    TimeUnit.MILLISECONDS.sleep(200);
                } catch (BlockException e1) {
                    blockCount++;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        SentinelDemo3Output output = new SentinelDemo3Output();
        System.out.println(MessageFormatUtil.format("Rest Service[{}], param[{}]!", this.getClass().getSimpleName(), input));
        output.setSuccessCount(successCount);
        output.setBlockCount(blockCount);
        return null;
    }

    private void defineDegradeRule(SentinelDemo3Input input) {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource(RESOURCE_NAME);
        rule.setCount(input.getCount());
        rule.setGrade(input.getGrade());
        rule.setTimeWindow(input.getTimeWindow());
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

}